<!--
* @author wn
* @date 2022/04/27 15:02:26
* @description: 轮播图 组件  宽高 由使用处父容器决定
* 宽高 由使用处父容器决定
* props:轮播图数据-sliders 是否自动轮播-autoPlay 间隔时长-duration
* fade 显示的图片加上    active 激活小点
!-->
<template>
	<div class="xtx-carousel" @mouseenter="stop()" @mouseleave="start()">
		<!-- 图片容器 -->
		<ul class="carousel-body">
			<!-- fade 显示的图片加上 -->
			<li
				class="carousel-item"
				v-for="(item, i) in sliders"
				:key="i"
				:class="{ fade: index === i }"
			>
				<!-- 图片 -->
				<RouterLink v-if="item.imgUrl" to="/">
					<img v-lazy="item.imgUrl" alt="" />
				</RouterLink>
				<!-- 商品列表 item=[goods1,goods2,。。。]-->
				<div v-else class="slider">
					<RouterLink
						v-for="goods in item"
						:key="goods.id"
						:to="`/product/${goods.id}`"
					>
						<img v-lazy="goods.picture" alt="" />
						<p class="name ellipsis">{{ goods.name }}</p>
						<p class="price">&yen;{{ goods.price }}</p>
					</RouterLink>
				</div>
			</li>
		</ul>
		<!-- 上一张 -->
		<a @click="toggle(-1)" href="javascript:;" class="carousel-btn prev">
			<i class="iconfont icon-angle-left"></i>
		</a>
		<!-- 下一张 -->
		<a @click="toggle(1)" href="javascript:;" class="carousel-btn next">
			<i class="iconfont icon-angle-right"></i>
		</a>
		<!-- 指示器 -->
		<div class="carousel-indicator">
			<!-- active 激活点 -->
			<span
				@click="index = i"
				v-for="(item, i) in sliders"
				:key="i"
				:class="{ active: index === i }"
			></span>
		</div>
	</div>
</template>

<script>
import { onUnmounted, ref, watch } from 'vue'
export default {
	name: 'XtxCarousel',
	props: {
		// 轮播图数据
		sliders: {
			type: Array,
			default: () => [],
		},
		// 是否自动轮播
		autoPlay: {
			type: Boolean,
			default: false,
		},
		// 间隔时长
		duration: {
			type: Number,
			default: 3000,
		},
	},
	setup(props) {
		// 控制显示图片的索引
		const index = ref(0)
		// 1. 自动轮播图的逻辑
		let timer = null
		const autoPlayFn = () => {
			// 防止定时器重复添加
			clearInterval(timer)
			// 自动播放，每隔多久切换索引
			timer = setInterval(() => {
				index.value++
				if (index.value >= props.sliders.length) {
					index.value = 0
				}
			}, props.duration)
		}
		/**
		 * 需要监听sliders数据变化，判断如果有数据且autoPlay是true
		 * immediate: true 静态数据 没有变化 newVal就是数据
		 * sliders 是 props对象的一个属性  需要函数返回
		 * 1 主页 sliders 是 reactive 数组  reactive 自带 深度监视 []->[5] 触发
		 * 2 猜你喜欢   sliders 是 reactive 数组 []->[[],[],[],[]] 无法深度监视
		 * deep:true  要开启深度监视才可以 监视其变化
		 */
		watch(
			() => props.sliders,
			newVal => {
				if (newVal.length && props.autoPlay) {
					autoPlayFn()
				}
			},
			{ immediate: true, deep: true }
		)

		// 2. 鼠标进入暂停  离开开启自动播放（有开启条件）
		const stop = () => {
			if (timer) clearInterval(timer)
		}
		const start = () => {
			if (props.sliders.length && props.autoPlay) autoPlayFn()
		}

		// 3. 点击点点可以切换，上一张下一张
		const toggle = step => {
			// 将要改变的索引
			const newIndex = index.value + step
			// 最后一张 点击下一张  返回第一张
			if (newIndex > props.sliders.length - 1) {
				index.value = 0
				return
			}
			// 第一张 点击上一张  返回最后一张
			if (newIndex < 0) {
				index.value = props.sliders.length - 1
				return
			}
			// 正常
			index.value = newIndex
		}

		// 4. 组件卸载，清除定时器
		onUnmounted(() => clearInterval(timer))

		return { index, stop, start, toggle }
	},
}
</script>
<style scoped lang="less">
.xtx-carousel {
	width: 100%;
	height: 100%;
	min-width: 300px;
	min-height: 150px;
	position: relative;
	.carousel {
		&-body {
			width: 100%;
			height: 100%;
		}
		&-item {
			width: 100%;
			height: 100%;
			position: absolute;
			left: 0;
			top: 0;
			opacity: 0;
			transition: opacity 0.5s linear;
			&.fade {
				opacity: 1;
				z-index: 1;
			}
			img {
				width: 100%;
				height: 100%;
			}
		}
		&-indicator {
			position: absolute;
			left: 0;
			bottom: 20px;
			z-index: 2;
			width: 100%;
			text-align: center;
			span {
				display: inline-block;
				width: 12px;
				height: 12px;
				background: rgba(0, 0, 0, 0.2);
				border-radius: 50%;
				cursor: pointer;
				~ span {
					margin-left: 12px;
				}
				&.active {
					background: #fff;
				}
			}
		}
		&-btn {
			position: absolute;
			top: 228px;
			width: 44px;
			height: 44px;
			background: rgba(0, 0, 0, 0.2);
			color: #fff;
			border-radius: 50%;
			z-index: 2;
			text-align: center;
			line-height: 44px;
			opacity: 0;
			transition: all 0.5s;
			&.prev {
				left: 20px;
			}
			&.next {
				right: 20px;
			}
		}
	}
	&:hover {
		.carousel-btn {
			opacity: 1;
		}
	}
}
// 轮播商品
.slider {
	display: flex;
	justify-content: space-around;
	padding: 0 40px;
	> a {
		display: flex;
		flex-direction: column;
		align-items: center;
		width: 240px;
		text-align: center;
		img {
			padding: 20px;
			width: 230px !important;
			height: 230px !important;
		}
		.name {
			width: 100%;
			font-size: 16px;
			color: #666;
			padding: 0 40px;
		}
		.price {
			font-size: 16px;
			color: @priceColor;
			margin-top: 15px;
		}
	}
}
</style>
